using System;
using System.Diagnostics;
using System.Drawing;

namespace iPhoneUI
{
    // These structures, enumerations and p/invoke signatures come from
    // wingdi.h in the Windows Mobile 5.0 Pocket PC SDK
    public static class GraphicsAlphaExtensions
    {
        public static void AlphaBlend(this Graphics graphics, Image image, byte sourceConstantAlpha, int x, int y)
        {
            Debug.Assert(image != null);

            using (Graphics gxSrc = Graphics.FromImage(image))
            {
                BlendFunction blendFunction;
                blendFunction.BlendOp = NativeMethods.AC_SRC_OVER;   // Only supported blend operation
                blendFunction.BlendFlags = 0;           // Documentation says put 0 here
                blendFunction.SourceConstantAlpha = sourceConstantAlpha;    // Constant alpha factor
                blendFunction.AlphaFormat = 0;

                IntPtr hdcDst = graphics.GetHdc();
                IntPtr hdcSrc = gxSrc.GetHdc();
                NativeMethods.AlphaBlend(hdcDst, x, y, image.Width, image.Height, hdcSrc, 0, 0, image.Width, image.Height, blendFunction);
                graphics.ReleaseHdc(hdcDst);    // Required cleanup to GetHdc()
                gxSrc.ReleaseHdc(hdcSrc);       // Required cleanup to GetHdc()
            }
        }

        public static void AlphaBlend(this Graphics graphics, Image image, byte sourceConstantAlpha, Rectangle destRect, Rectangle srcRect)
        {
            Debug.Assert(image != null);

            using (Graphics gxSrc = Graphics.FromImage(image))
            {
                BlendFunction blendFunction;
                blendFunction.BlendOp = NativeMethods.AC_SRC_OVER;   // Only supported blend operation
                blendFunction.BlendFlags = 0;           // Documentation says put 0 here
                blendFunction.SourceConstantAlpha = sourceConstantAlpha;    // Constant alpha factor
                blendFunction.AlphaFormat = 0;

                IntPtr hdcDst = graphics.GetHdc();
                IntPtr hdcSrc = gxSrc.GetHdc();
                NativeMethods.AlphaBlend(hdcDst, destRect.X, destRect.Y, destRect.Width, destRect.Height, hdcSrc, srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, blendFunction);
                graphics.ReleaseHdc(hdcDst);    // Required cleanup to GetHdc()
                gxSrc.ReleaseHdc(hdcSrc);       // Required cleanup to GetHdc()
            }
        }

        public static void AlphaBlend(this Graphics graphics, IImage image, Rectangle destinationBounds)
        {
            Debug.Assert(image != null);

            // The draw method expects a win32 RECT where Width and Height fields are right and bottom
            destinationBounds.Width += destinationBounds.X;
            destinationBounds.Height += destinationBounds.Y;

            IntPtr hdcDest = graphics.GetHdc();
            image.Draw(hdcDest, ref destinationBounds, IntPtr.Zero);
            graphics.ReleaseHdc(hdcDest);
        }
    }
}